package cn.tedu.ivoscm.application.service.impl;

import cn.tedu.ivoscm.application.mapper.ApplicationMapper;
import cn.tedu.ivoscm.application.pojo.dto.ApplicationQuery;
import cn.tedu.ivoscm.application.pojo.dto.ApplicationSaveParam;
import cn.tedu.ivoscm.application.pojo.entity.Application;
import cn.tedu.ivoscm.application.pojo.vo.ApplicationVO;
import cn.tedu.ivoscm.application.service.ApplicationService;
import cn.tedu.ivoscm.audit.mapper.AuditMapper;
import cn.tedu.ivoscm.audit.pojo.vo.AuditVO;
import cn.tedu.ivoscm.audit.service.AuditService;
import cn.tedu.ivoscm.audit.service.impl.AuditServiceImpl;
import cn.tedu.ivoscm.base.enums.ApplicationStatusEnum;
import cn.tedu.ivoscm.user.mapper.UserMapper;
import cn.tedu.ivoscm.user.pojo.dto.UserQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
@Slf4j
@Service
public class ApplicationServiceImpl implements ApplicationService {
    @Autowired
    private ApplicationMapper applicationMapper;
    @Autowired
    private AuditService auditService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuditMapper auditMapper;

    @Override
    public void save(ApplicationSaveParam asp) {
        log.debug("保存申请业务，参数：{}", asp);
        Application a = new Application();
        BeanUtils.copyProperties(asp, a);
        a.setCreateTime(new Date());
        a.setStatus(ApplicationStatusEnum.PENDING.getCode());  // 默认为待审批
        log.debug("{}", a);
        /* 问题：新增审批数据时无id
           原因： 执行对应的SQL后，并未把刚生成的申请单id回填至Application对象中
           解决办法：见Mapper.xml
         */
        applicationMapper.insert(a);

        // 调用审批业务层，添加1~2条审批数据
        auditService.insertAudit(a);
    }

    @Override
    public List<ApplicationVO> select(ApplicationQuery aq) {
        log.debug("查询申请列表业务，参数：{}", aq);
        List<ApplicationVO> list = applicationMapper.select(aq);
        // 遍历list，为每个VO对象北泉审批人数据
        for (int i = 0; i < list.size(); i++) {
            ApplicationVO avo = list.get(i);
            // 自定义方法，给VO做补全
            fillAuditUserNameList(avo);
        }
        return list;
    }

    // 此方法不会产生额外的申请单VO
    private void fillAuditUserNameList(ApplicationVO avo) {
        // 1. 准备空集合，分别保存当前传入申请单对应审批人的id与姓名
        List<Long> auditUserIdList = new ArrayList<>();
        List<String> auditUserNameList = new ArrayList<>();
        // 2. 通过申请单id查询审批单VO集合
        List<AuditVO> auditList = auditService.selectAuditByApplicationId(avo.getId());
        // 3. 遍历审批单VO
        for (int i = 0; i < auditList.size(); i++) {
            AuditVO auditVO = auditList.get(i);
            // 4. 获取审批人id，加入表
            Long auditUserId = auditVO.getAuditUserId();
            auditUserIdList.add(auditUserId);
            // 5. 查询其姓名
            UserQuery uq = new UserQuery();
            uq.setId(auditUserId);
            String username = userMapper.selectUser(uq).get(0).getUsername();
            auditUserNameList.add(username);
            // 6. 拼接工具拼接用户名
            StringJoiner sj = new StringJoiner(", ");
            for (int j = 0; j < auditUserNameList.size(); j++) {
                sj.add(auditUserNameList.get(j));
            }
            // 7. 设置VO属性
            avo.setAuditUserIdList(auditUserIdList);
            avo.setAuditUserNameList(sj.toString());
        }
    }

    @Override
    public void cancel(Long id) {
        log.debug("取消申请业务，参数：{}", id);
        // 业务1：更改申请单状态为撤销
        Application a = new Application();
        a.setId(id);
        a.setStatus(ApplicationStatusEnum.CANCEL.getCode());
        a.setUpdateTime(new Date());
        applicationMapper.update(a);

        // 业务2：将此申请单对应的所有审核单删除
        auditMapper.deleteByApplicationId(id);
    }
}
